/**
  ******************************************************************************
  * @file    IAP/IAP_Main/Inc/flash_if.h
  * @author  MCD Application Team
  * @version V1.5.0
  * @date    17-February-2017
  * @brief   This file provides all the headers of the flash_if functions.
  ******************************************************************************
  * @attention
  *
  * <h2><center>&copy; Copyright (c) 2017 STMicroelectronics International N.V.
  * All rights reserved.</center></h2>
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted, provided that the following conditions are met:
  *
  * 1. Redistribution of source code must retain the above copyright notice,
  *    this list of conditions and the following disclaimer.
  * 2. Redistributions in binary form must reproduce the above copyright notice,
  *    this list of conditions and the following disclaimer in the documentation
  *    and/or other materials provided with the distribution.
  * 3. Neither the name of STMicroelectronics nor the names of other
  *    contributors to this software may be used to endorse or promote products
  *    derived from this software without specific written permission.
  * 4. This software, including modifications and/or derivative works of this
  *    software, must execute solely and exclusively on microcontroller or
  *    microprocessor devices manufactured by or for STMicroelectronics.
  * 5. Redistribution and use of this software other than as permitted under
  *    this license is void and will automatically terminate your rights under
  *    this license.
  *
  * THIS SOFTWARE IS PROVIDED BY STMICROELECTRONICS AND CONTRIBUTORS "AS IS"
  * AND ANY EXPRESS, IMPLIED OR STATUTORY WARRANTIES, INCLUDING, BUT NOT
  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
  * PARTICULAR PURPOSE AND NON-INFRINGEMENT OF THIRD PARTY INTELLECTUAL PROPERTY
  * RIGHTS ARE DISCLAIMED TO THE FULLEST EXTENT PERMITTED BY LAW. IN NO EVENT
  * SHALL STMICROELECTRONICS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
  * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
  * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  *
  ******************************************************************************
  */
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __FLASH_IF_H
#define __FLASH_IF_H

/* Includes ------------------------------------------------------------------*/
#include "gd32f30x.h"
#include "gd32f30x_hal_def.h"

/* Base address of the Flash sectors */
#define ADDR_FLASH_WP_SECTOR_0     ((uint32_t)0x08000000) /* Base @ of Sector 0, 4 Kbyte */
#define ADDR_FLASH_WP_SECTOR_1     ((uint32_t)0x08001000) /* Base @ of Sector 1, 4 Kbyte */
#define ADDR_FLASH_WP_SECTOR_2     ((uint32_t)0x08002000) /* Base @ of Sector 2, 4 Kbyte */
#define ADDR_FLASH_WP_SECTOR_3     ((uint32_t)0x08003000) /* Base @ of Sector 3, 4 Kbyte */
#define ADDR_FLASH_WP_SECTOR_4     ((uint32_t)0x08004000) /* Base @ of Sector 4, 4 Kbyte */
#define ADDR_FLASH_WP_SECTOR_5     ((uint32_t)0x08005000) /* Base @ of Sector 5, 4 Kbyte */
#define ADDR_FLASH_WP_SECTOR_6     ((uint32_t)0x08006000) /* Base @ of Sector 6, 4 Kbyte */
#define ADDR_FLASH_WP_SECTOR_7     ((uint32_t)0x08007000) /* Base @ of Sector 7, 4 Kbyte */
#define ADDR_FLASH_WP_SECTOR_8     ((uint32_t)0x08008000) /* Base @ of Sector 8, 4 Kbyte */
#define ADDR_FLASH_WP_SECTOR_9     ((uint32_t)0x08009000) /* Base @ of Sector 9, 4 Kbyte */
#define ADDR_FLASH_WP_SECTOR_10    ((uint32_t)0x0800A000) /* Base @ of Sector 10, 4 Kbyte */
#define ADDR_FLASH_WP_SECTOR_11    ((uint32_t)0x0800B000) /* Base @ of Sector 11, 4 Kbyte */
#define ADDR_FLASH_WP_SECTOR_12    ((uint32_t)0x0800C000) /* Base @ of Sector 12, 4 Kbyte */
#define ADDR_FLASH_WP_SECTOR_13    ((uint32_t)0x0800D000) /* Base @ of Sector 13, 4 Kbyte */
#define ADDR_FLASH_WP_SECTOR_14    ((uint32_t)0x0800E000) /* Base @ of Sector 14, 4 Kbyte */
#define ADDR_FLASH_WP_SECTOR_15    ((uint32_t)0x0800F000) /* Base @ of Sector 15, 4 Kbyte */
#define ADDR_FLASH_WP_SECTOR_16    ((uint32_t)0x08010000) /* Base @ of Sector 16, 4 Kbyte */
#define ADDR_FLASH_WP_SECTOR_17    ((uint32_t)0x08011000) /* Base @ of Sector 17, 4 Kbyte */
#define ADDR_FLASH_WP_SECTOR_18    ((uint32_t)0x08012000) /* Base @ of Sector 18, 4 Kbyte */
#define ADDR_FLASH_WP_SECTOR_19    ((uint32_t)0x08013000) /* Base @ of Sector 19, 4 Kbyte */
#define ADDR_FLASH_WP_SECTOR_20    ((uint32_t)0x08014000) /* Base @ of Sector 20, 4 Kbyte */
#define ADDR_FLASH_WP_SECTOR_21    ((uint32_t)0x08015000) /* Base @ of Sector 21, 4 Kbyte */
#define ADDR_FLASH_WP_SECTOR_22    ((uint32_t)0x08016000) /* Base @ of Sector 22, 4 Kbyte */
#define ADDR_FLASH_WP_SECTOR_23    ((uint32_t)0x08017000) /* Base @ of Sector 23, 4 Kbyte */
#define ADDR_FLASH_WP_SECTOR_24    ((uint32_t)0x08018000) /* Base @ of Sector 24, 4 Kbyte */
#define ADDR_FLASH_WP_SECTOR_25    ((uint32_t)0x08019000) /* Base @ of Sector 25, 4 Kbyte */
#define ADDR_FLASH_WP_SECTOR_26    ((uint32_t)0x0801A000) /* Base @ of Sector 26, 4 Kbyte */
#define ADDR_FLASH_WP_SECTOR_27    ((uint32_t)0x0801B000) /* Base @ of Sector 27, 4 Kbyte */
#define ADDR_FLASH_WP_SECTOR_28    ((uint32_t)0x0801C000) /* Base @ of Sector 28, 4 Kbyte */
#define ADDR_FLASH_WP_SECTOR_29    ((uint32_t)0x0801D000) /* Base @ of Sector 29, 4 Kbyte */
#define ADDR_FLASH_WP_SECTOR_30    ((uint32_t)0x0801E000) /* Base @ of Sector 30, 4 Kbyte */
#define ADDR_FLASH_WP_SECTOR_31    ((uint32_t)0x0801F000) /* Base @ of Sector 31, 125~all Kbyte */

/* Error code */
enum
{
  FLASHIF_OK = 0,
  FLASHIF_ERASEKO,
  FLASHIF_WRITINGCTRL_ERROR,
  FLASHIF_WRITING_ERROR
};

enum{
  FLASHIF_PROTECTION_NONE         = 0,
  FLASHIF_PROTECTION_PCROPENABLED = 0x1,
  FLASHIF_PROTECTION_WRPENABLED   = 0x2,
  FLASHIF_PROTECTION_RDPENABLED   = 0x4,
};

/* Configures*/
///////////////////////////////////////////////////////////////
#define MAX_FLASH_ADDRESS               (FMC_BANK0_END_ADDRESS)


#define FMC_PAGE_SIZE_BANK0             ((uint16_t)0x800U)
#define FMC_PAGE_SIZE_BANK1             ((uint16_t)0x1000U)

/* Define the address from where user application will be loaded.
   Note: the 1st sector 0x08000000-0x08003FFF is reserved for the IAP code */
#define APPLICATION_ADDRESS             (uint32_t)0x08008000

/* End of the Flash address */
#define USER_FLASH_END_ADDRESS          (uint32_t)0x08017FFF
/* Define the user application size */
#define USER_FLASH_SIZE                 (USER_FLASH_END_ADDRESS - APPLICATION_ADDRESS + 1)


/* Define bitmap representing user flash area that could be write protected */
#define FLASH_SECTOR_TO_BE_PROTECTED (OB_WP_0 | OB_WP_1 | OB_WP_2 | OB_WP_3 |\
                                      OB_WP_4 | OB_WP_5 | OB_WP_6 | OB_WP_7 )

/* Exported macro ------------------------------------------------------------*/
extern unsigned char Erase_NbSectors; //要擦除的块数量
/* Exported functions ------------------------------------------------------- */
uint32_t FLASH_Read(uint32_t ReadAddress) ;
void              FLASH_If_Init(void);
uint32_t          FLASH_If_Erase(uint32_t StartSector);
uint32_t          FLASH_If_Erase_Sector(uint32_t StartSector,uint32_t fsize);
uint32_t          FLASH_If_Write(uint32_t FlashAddress, uint32_t* Data, uint32_t DataLength);
uint16_t          FLASH_If_GetWriteProtectionStatus(void);
HAL_StatusTypeDef FLASH_If_WriteProtectionConfig(uint32_t modifier);
uint32_t GetSector(uint32_t Address);
uint16_t GetPage(uint32_t address);

//////////////////////////////////////////////////////////////////////////////////////////
#include <stdio.h>
#include "gd32f30x.h"

/* FMC sector information */
typedef struct
{
    uint32_t sector_name;                                         /*!< the name of the sector */
    uint32_t sector_num;                                          /*!< the number of the sector */
    uint32_t sector_size;                                         /*!< the size of the sector */
    uint32_t sector_start_addr;                                   /*!< the start address of the sector */
    uint32_t sector_end_addr;                                     /*!< the end address of the sector */
} fmc_sector_info_struct;

/* sector size */
#define SIZE_16KB                  ((uint32_t)0x00004000U)        /*!< size of 16KB*/
#define SIZE_64KB                  ((uint32_t)0x00010000U)        /*!< size of 64KB*/
#define SIZE_128KB                 ((uint32_t)0x00020000U)        /*!< size of 128KB*/
#define SIZE_256KB                 ((uint32_t)0x00040000U)        /*!< size of 256KB*/

/* FMC BANK address */
#define FMC_START_ADDRESS          FLASH_BASE                               /*!< FMC start address */
#define FMC_BANK0_START_ADDRESS    FMC_START_ADDRESS                        /*!< FMC BANK0 start address */
#define FMC_BANK1_START_ADDRESS    ((uint32_t)0x08080000U)                  /*!< FMC BANK1 start address */
#define FMC_END_ADDRESS            (FLASH_BASE + (FMC_SIZE * 1024) - 1)     /*!< FMC end address */
#define FMC_MAX_END_ADDRESS        ((uint32_t)0x08300000U)                  /*!< FMC maximum end address */

/* FMC error message */
#define FMC_WRONG_SECTOR_NAME      ((uint32_t)0xFFFFFFFFU)        /*!< wrong sector name*/
#define FMC_WRONG_SECTOR_NUM       ((uint32_t)0xFFFFFFFFU)        /*!< wrong sector number*/
#define FMC_INVALID_SIZE           ((uint32_t)0xFFFFFFFFU)        /*!< invalid sector size*/
#define FMC_INVALID_ADDR           ((uint32_t)0xFFFFFFFFU)        /*!< invalid sector address*/

/* get the sector number, size and range of the given address */
fmc_sector_info_struct fmc_sector_info_get(uint32_t addr);
/* get the sector number by sector name */
uint32_t sector_name_to_number(uint32_t sector_name);
/* erases the sector of a given sector number */
void fmc_erase_sector_by_address(uint32_t address);
/* write 32 bit length data to a given address */
void fmc_write_32bit_data(uint32_t address, uint16_t length, int32_t* data_32);
/* read 32 bit length data from a given address */
void fmc_read_32bit_data(uint32_t address, uint16_t length, int32_t* data_32);
/* write 16 bit length data to a given address */
void fmc_write_16bit_data(uint32_t address, uint16_t length, int16_t* data_16);
/* read 16 bit length data from a given address */
void fmc_read_16bit_data(uint32_t address, uint16_t length, int16_t* data_16);
/* write 8 bit length data to a given address */
void fmc_write_8bit_data(uint32_t address, uint16_t length, int8_t* data_8);
/* read 8 bit length data from a given address */
void fmc_read_8bit_data(uint32_t address, uint16_t length, int8_t* data_8);

#endif  /* __FLASH_IF_H */

/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
